#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "editor.h"
#include "projectcontextmenu.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent), ui(new Ui::MainWindowClass)
{
    ui->setupUi(this);
    initSettings();
    for (int i = 0; i < MaxRecentFiles; ++i) {
         recentFileActs[i] = new QAction(ui->menu_File);
         recentFileActs[i]->setVisible(false);
         recentProjectBttns[i] = new QPushButton(ui->verticalLayoutWidget);
         recentProjectBttns[i]->setVisible(false);
         recentProjectBttns[i]->setFlat(true);
         connect(recentProjectBttns[i], SIGNAL(clicked()), recentFileActs[i], SLOT(trigger()));
         connect(recentFileActs[i], SIGNAL(triggered()),
                 this, SLOT(openRecentProject()));
         ui->menu_File->insertAction(ui->actionClose_tab, recentFileActs[i]);
         ui->verticalLayout->insertWidget(0,recentProjectBttns[i], 0, Qt::AlignBottom);
     }
    ui->menu_File->insertSeparator(recentFileActs[MaxRecentFiles-1]);
    recentProjectsInit();
    ui->actionIndent->setShortcut(QKeySequence("Tab"));
    ui->actionUnindent->setShortcut(QKeySequence("Shift+Tab"));
    menu =new ProjectContextMenu(ui->projectFiles);
    currEditor = 0;
    this->proSettings = new ProgramSettings(0);
    connect(ui->openedFilesTabWidget, SIGNAL(currentChanged(int)), this, SLOT(setCurrentTab(int)));
    connect(ui->projectFiles, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(projectFilesContext(const QPoint &)));
    connect(ui->searchEngines->lineEdit(), SIGNAL(returnPressed()), this, SLOT(newSearch()));
    connect(ui->searchEngines->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(searchStringChanged(QString)));
    connect(this->proSettings, SIGNAL(currentChanged(int)), this, SLOT(editorTabPositionChange(int)));
    ui->mainToolBar->addWidget(ui->searchEngines);
}

void MainWindow::initSettings()
{
    QSettings programSettings("SSC", "Shushi XVIII");
    if(programSettings.value("First run",true).toBool())
    {
        // Setting default settings
        qDebug("This is first run");
        programSettings.setValue("User login", "");
        programSettings.setValue("User password", "");
        programSettings.setValue("Wordwrap", true);
        programSettings.setValue("Brace match",true);
        programSettings.setValue("Open unknown files as text", true);
        programSettings.setValue("Files tab position", 0);
        programSettings.setValue("Network automat", true);
        programSettings.setValue("Proxy", false);
        programSettings.setValue("Proxy login", "");
        programSettings.setValue("Proxy password", "");
        programSettings.setValue("DNS", "127.000.000.001");
        programSettings.setValue("Keyword color", QColor(128, 128, 128, 2));
        programSettings.setValue("Comment color", QColor(128, 128, 128, 2));
        programSettings.setValue("Quoted text color", QColor(128, 128, 128, 2));
        programSettings.setValue("Plain text color", QColor(128, 128, 128, 2));
        programSettings.setValue("Build apps automat", true);
        programSettings.setValue("Compiler path", "");
        programSettings.setValue("Run arguments", "");
        programSettings.setValue("First run", false);
    }
    else
    {
        // Init settings
        qDebug("Running Settings");
    }
}

void MainWindow::recentProjectsInit()
{
    QSettings programSettings("SSC", "Shushi XVIII");
    QStringList files = programSettings.value("recentFileList").toStringList();
    int numRecentFiles = qMin(files.size(), (int)MaxRecentFiles);
    for (int i = 0; i < numRecentFiles; ++i) {
        QString text = tr("&%1 %2").arg(i + 1).arg(QFileInfo(files[i]).fileName());
        qDebug(text.toStdString().c_str());
        qDebug("^");
        recentFileActs[i]->setText(text);
        recentFileActs[i]->setData(files[i]);
        recentFileActs[i]->setVisible(true);
        recentProjectBttns[i]->setText(text);
        recentProjectBttns[i]->setVisible(true);
    }
    for (int j = numRecentFiles; j < MaxRecentFiles; ++j)
    {
        recentProjectBttns[j]->setVisible(false);
        recentFileActs[j]->setVisible(false);
    }
}

MainWindow::~MainWindow()
{
    delete ui;
    delete this->currEditor;
    delete this->menu;
    delete this->proSettings;
}

void MainWindow::on_action_New_file_triggered()
{
    EEditor *ed = new EEditor(ui->openedFilesTabWidget);
    if(this->proSettings->wordWrap())
        ed->setWrapMode(QsciScintilla::WrapWord);
    ed->setFont(this->proSettings->editorFont());
    ui->openedFilesTabWidget->addTab(ed, "Untitled");
    ui->openedFilesTabWidget->setCurrentWidget(ed);
}

void MainWindow::on_action_Undo_triggered()
{
    if(ui->openedFilesTabWidget->currentIndex()>0)
    {
        currEditor->undo();
    }
}

void MainWindow::on_action_Redo_triggered()
{
    if(ui->openedFilesTabWidget->currentIndex()>0)
    {
        currEditor->redo();
    }
}

void MainWindow::on_action_Cut_triggered()
{
    if(ui->openedFilesTabWidget->currentIndex()>0)
    {
        currEditor->cut();
    }
}

void MainWindow::on_action_Select_all_triggered()
{
    if(ui->openedFilesTabWidget->currentIndex()>0)
    {
        currEditor->selectAll();
    }
}

void MainWindow::on_action_Copy_triggered()
{
    if(ui->openedFilesTabWidget->currentIndex()>0)
    {
        currEditor->copy();
    }
}

void MainWindow::on_action_Paste_triggered()
{
    if(ui->openedFilesTabWidget->currentIndex()>0)
    {
        currEditor->paste();
    }
}

void MainWindow::on_action_Delete_triggered()
{
    if(ui->openedFilesTabWidget->currentIndex()>0)
    {
        currEditor->clear();
    }
}

void MainWindow::on_action_Open_file_triggered(QString path)
{
     QString fileName = path;
     int max = ui->openedFilesTabWidget->count();
     for(int i=1; i<max;i++)
        {
            if(((EEditor*)ui->openedFilesTabWidget->widget(i))->filePath().compare(path) == 0 &&
               !((EEditor*)ui->openedFilesTabWidget->widget(i))->filePath().isNull())
                return;
        }
     if (fileName.isNull())
         fileName = QFileDialog::getOpenFileName(this,
             tr("Open File"), "", "C++ Files (*.cpp *.h)");

     if (!fileName.isEmpty()) {
         QFile file(fileName);
         QFileInfo nfo(file);
         if(nfo.suffix().compare("h") == 0 || nfo.suffix().compare("cpp") == 0 || nfo.suffix().compare("c") == 0 ||
             nfo.suffix().compare("txt") ==0 )
         {
             if (file.open(QFile::ReadOnly | QFile::Text))
             {
                 this->on_action_New_file_triggered();
                 currEditor->setText(file.readAll());
                 currEditor->setFilePath(fileName);
                 QFileInfo nfo(file);
                 ui->openedFilesTabWidget->setTabText(ui->openedFilesTabWidget->currentIndex(),nfo.fileName());
             }
             else
                 QMessageBox::critical(0,QString("Error in opening file %1").arg(fileName),file.errorString());
         }
         else
             QDesktopServices::openUrl(QUrl(QString(fileName)));
     }
}

void MainWindow::on_projectFiles_doubleClicked(QModelIndex index)
{
    if(!ui->projectFiles->currentItem()->text(1).isNull() &&
       ui->projectFiles->currentItem()->text(2).compare("Folder", Qt::CaseInsensitive) !=0 &&
       ui->projectFiles->currentItem()->text(2).compare("Project", Qt::CaseInsensitive) !=0 )
    {
        QString filePath = ui->projectFiles->currentItem()->text(1)+"/"+ui->projectFiles->currentItem()->text(0);
        this->on_action_Open_file_triggered(filePath);
    }
}


void MainWindow::documentModified()
{
    if(currEditor!=0)
    {
       int index = ui->openedFilesTabWidget->currentIndex();
       if(ui->openedFilesTabWidget->tabText(index).at(ui->openedFilesTabWidget->tabText(index).size()-1) != '*')
            ui->openedFilesTabWidget->setTabText(ui->openedFilesTabWidget->currentIndex(),
                                            ui->openedFilesTabWidget->tabText(index)+"*");
    }

}

void MainWindow::setCurrentTab(int index)
{
    if(index!=0)
    {         
        currEditor = (EEditor*)ui->openedFilesTabWidget->widget(index);
        connect(currEditor,SIGNAL(textChanged()),this,SLOT(documentModified()));
    }
    else
    {
        currEditor = 0;
    }
}


void MainWindow::closeCurrentTab()
{
    int i = ui->openedFilesTabWidget->currentIndex();
    if(i!=0)
    {
        QString tabText = ui->openedFilesTabWidget->tabText(ui->openedFilesTabWidget->currentIndex());
        if(tabText.at(tabText.size()-1) != '*')
            ui->openedFilesTabWidget->removeTab(i);
        else
        {
            QMessageBox msgBox;
            msgBox.setText(QString("The file %1 has been modified.").arg(tabText.remove(tabText.size()-1,1)));
            msgBox.setInformativeText("Do you want to save your changes?");
            msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
            msgBox.setDefaultButton(QMessageBox::Save);
            msgBox.setIcon(QMessageBox::Question);
            msgBox.setWindowIcon(QIcon(QPixmap(QString::fromUtf8(":/icons/res/icons/question-balloon.png"))));
            int ret = msgBox.exec();
            switch (ret)
            {
               case QMessageBox::Save:
                   if(currEditor->save())
                       ui->openedFilesTabWidget->removeTab(i);
                   break;
               case QMessageBox::Discard:
                   ui->openedFilesTabWidget->removeTab(i);
                   break;
               case QMessageBox::Cancel:
                   return;
                   break;
               default:
                   qDebug("default");
                   break;
             }
        }
    }
    else
        ui->openedFilesTabWidget->removeTab(i);
}

void MainWindow::on_action_Save_triggered()
{
    if(currEditor!=0)
    {
        currEditor->save();
        QFileInfo nfo(currEditor->filePath());
        int i = ui->openedFilesTabWidget->currentIndex();
        ui->openedFilesTabWidget->setTabText(i, nfo.fileName());
    }
}

void MainWindow::on_action_Save_as_triggered()
{
    if(currEditor!=0)
        currEditor->saveAs();
}

void MainWindow::projectFilesContext(const QPoint &point)
{
    if(ui->projectFiles->currentItem() != 0 && ui->projectFiles->currentItem()->isSelected())
    {
        menu->move(ui->projectFiles->mapToGlobal(point));
        menu->setObject(ui->projectFiles->currentItem());
        menu->show();
    }
}

void MainWindow::newSearch()
{
    switch(ui->searchEngines->currentIndex())
    {
        case 0:
        {
            //Gooogle
            QDesktopServices::openUrl(QUrl(QString("http://www.google.com/search?q=%1").arg(ui->searchEngines->lineEdit()->text())));
        }
        break;
        case 1:
        {
            // Yandex
            QDesktopServices::openUrl(QUrl(QString("http://yandex.ru/yandsearch?text=%1").arg(ui->searchEngines->lineEdit()->text())));
        }
        break;
        case 2:
        {
            // Mail
            QDesktopServices::openUrl(QUrl(QString("http://go.mail.ru/search?q=%1").arg(ui->searchEngines->lineEdit()->text())));
        }
        break;
        case 3:
        {
            // Yahoo
            QDesktopServices::openUrl(QUrl(QString("http://search.yahoo.com/search?p=%1").arg(ui->searchEngines->lineEdit()->text())));
        }
        break;
        case 4:
        {
            // Rambler
            QDesktopServices::openUrl(QUrl(QString("http://nova.rambler.ru/search?query=%1").arg(ui->searchEngines->lineEdit()->text())));
        }
        break;
        default:
            QMessageBox::aboutQt(this,ui->searchEngines->currentText());
    }
}

void MainWindow::searchStringChanged(QString value)
{
    if(!value.isEmpty())
        this->m_searchString = value;
}

void MainWindow::on_searchEngines_currentIndexChanged(int index)
{
    this->ui->searchEngines->setEditText(m_searchString);
}

void MainWindow::on_actionClose_tab_triggered()
{
    this->closeCurrentTab();
}

void MainWindow::on_openedFilesTabWidget_customContextMenuRequested(QPoint pos)
{
    QMenu *menu = new QMenu;
    menu->addAction(this->ui->actionClose_tab);
    menu->exec(ui->openedFilesTabWidget->mapToGlobal(pos));
}

void MainWindow::on_actionIndent_triggered()
{
    if(currEditor !=0)
    {
        int lineFrom, lineTo, indexFrom, indexTo;
        currEditor->getSelection(&lineFrom, &indexFrom, &lineTo, &indexTo);
        qDebug(QString::number(indexFrom).toStdString().c_str());
                qDebug(QString::number(indexTo).toStdString().c_str());
        if(lineFrom>-1)
                for(int i=lineFrom; i<=lineTo; i++)
                currEditor->indent(i);
        else if(lineFrom == lineTo)
            currEditor->insert("   ");
    }
}

void MainWindow::on_actionUnindent_triggered()
{
    if(currEditor !=0)
    {
        int lineFrom, lineTo, indexFrom, indexTo;
        currEditor->getSelection(&lineFrom, &indexFrom, &lineTo, &indexTo);
        for(int i=lineFrom; i<=lineTo; i++)
            currEditor->unindent(i);
    }
}

void MainWindow::on_action_Open_project_triggered(QString fileName)
{
    if(fileName.isEmpty() || fileName.isNull())
        fileName = QFileDialog::getOpenFileName(this,tr("Open Project"), "", "C++ Files (*.xml)");
    if (!fileName.isEmpty())
    {
         QFile file(fileName);
         QFileInfo nfo(file);
         if(nfo.suffix().compare("xml") == 0)
         {
            pro= EProject(ui->projectFiles);
            pro.open(fileName);
            if(!pro.hasError())
            {
                ui->projectInfo->setID(pro.id());
                ui->projectInfo->setName(pro.name());
                ui->projectInfo->setAuthor(pro.author());
                if(pro.tree() != 0)
                ui->projectFiles->addTopLevelItem(pro.tree());
                QSettings settings("SSC", "Shushi XVIII");
                QStringList files = settings.value("recentFileList").toStringList();
                files.removeAll(fileName);
                files.prepend(fileName);
                while (files.size() > MaxRecentFiles)
                files.removeLast();
                settings.setValue("recentFileList", files);
                this->recentProjectsInit();
            }
            else
                QMessageBox::critical(0,QString("Error in opening file %1").arg(fileName),file.errorString());
        }
        else
            QDesktopServices::openUrl(QUrl(QString(fileName)));
    }
}

void MainWindow::openRecentProject()
{
    QAction *action = qobject_cast<QAction *>(sender());
    if (action)
        on_action_Open_project_triggered(action->data().toString());
}

void MainWindow::on_action_Settings_program_triggered(bool checked)
{
        this->proSettings->show();
}

void MainWindow::editorTabPositionChange(int position)
{
    qDebug(QString::number(position).toStdString().c_str());
    switch(--position)
    {
        case 0:
            this->ui->openedFilesTabWidget->setTabPosition(QTabWidget::North);
            break;
        case 1:
            this->ui->openedFilesTabWidget->setTabPosition(QTabWidget::South);
            break;
        case 2:
            this->ui->openedFilesTabWidget->setTabPosition(QTabWidget::West);
            break;
        case 3:
            this->ui->openedFilesTabWidget->setTabPosition(QTabWidget::East);
            break;
        default:
            this->ui->openedFilesTabWidget->setTabPosition(QTabWidget::North);
            break;
    }

}

void MainWindow::on_openedFilesTabWidget_tabCloseRequested(int index)
{
    int i = ui->openedFilesTabWidget->currentIndex();
    ui->openedFilesTabWidget->setCurrentIndex(index);
    closeCurrentTab();
    ui->openedFilesTabWidget->setCurrentIndex(i);
}
